﻿using UnityEngine;
using System.Collections.Generic;
using XLua;

namespace Kylin
{
    public class AudioManager : SingletonMonobehaviour<AudioManager>,IManager
    {        
		AudioPool musicPool;
		AudioPool audioPool;

		private float globalAudioVolume = 1.0f;
		private float globalMusicVolume = 1.0f;

        public void OnInitialize()
        {
            if (musicPool == null)
                musicPool = new AudioPool("MusicSourcePool",gameObject.transform);
			
            if (audioPool == null)
                audioPool = new AudioPool("AudioSourcePool", gameObject.transform);
            
            for (int i = 0; i < 10; i++)
            {
                musicPool.AddAudioSource();
            }

            SetGolbalMusicVolume(LocalDataStorage.Instance.GetFloat("Music"));
            SetGlobalAudioVolume(LocalDataStorage.Instance.GetFloat("Effect"));
        }

        public void OnUpdateLogic()
        {
            
        }

        public void OnDestruct()
        {

        }

        [LuaCallCSharp]
        public void SetGlobalAudioVolume(float volume)
        {
            globalAudioVolume = volume;

            foreach(var asource in audioPool.Pool)
            {
                if (asource.audioSource.clip != null)
                {
                    asource.audioSource.volume = asource.defaultVolume * volume;
                }
            }
        }

        [LuaCallCSharp]
        public void SetGolbalMusicVolume(float volume)
        {
            globalMusicVolume = volume;
            foreach (var asource in musicPool.Pool)
            {
                if (asource.audioSource.clip != null)
                {
                    asource.audioSource.volume = asource.defaultVolume * volume;
                }
            }
        }

         
        [LuaCallCSharp]
        public void PlayAudio(string audioname, int musictype ,float volume,int channel,int option)
        {
            Debug.Log("play music" + audioname + " " + volume + " " + channel);
            
            if (string.IsNullOrEmpty(audioname)) return;

			AudioSourceData audioSourceData = null;
            bool isMusic = musictype == 1;
            if(isMusic)
            {                
                if(channel >= musicPool.Pool.Count)
                {
                    Debug.LogError("Error ,Do you realy need 10 more loop music ?");
                    return;
                }
                audioSourceData = musicPool.Pool[channel];
                audioSourceData.audioSource.loop = true;
                audioSourceData.audioSource.volume = volume * globalMusicVolume;
            }
            else
            {                
                for (int i = 0;i< audioPool.Pool.Count;i++)
                {
                    if(audioPool.Pool[i].audioSource.isPlaying == false)
                    {
                        audioSourceData = audioPool.Pool[i];
                        break;
                    }
                }
                if(audioSourceData == null)
                {
                    audioPool.AddAudioSource();
                    audioSourceData = audioPool.Pool[audioPool.Pool.Count - 1];
                    audioSourceData.audioSource.loop = false;
                }
                audioSourceData.audioSource.volume = volume * globalAudioVolume;
            }

            string path = string.Format("Audio/{0}", audioname);
            audioSourceData.audioSource.playOnAwake = false;                        
            audioSourceData.defaultVolume = volume;
            
            if (audioSourceData.audioSource.clip)
            {
                bool needReload = false;
                if (isMusic)
                {
                    if (audioSourceData.audioSource.clip.name == audioname)
                        return;
                    else
                    {
						needReload = true;                         
                    }
                }
                else
                {
                    if (audioSourceData.audioSource.clip.name == audioname)
                    {
                        ChangeAudioState(audioSourceData, (ControlMusic)option);
                    }
                    else
                    {
						needReload = true;
                    }
                }
                                   
				if(needReload)
                {
                    if (!string.IsNullOrEmpty(audioSourceData.resPath))
                    {
                        ResourceLoader.LoadAsset(audioSourceData.resPath);
                    }

                   ResourceLoader.LoadAssetAsync(path, (obj) => UpdateAudioOption(audioSourceData, (AudioClip)obj, (ControlMusic)option, path));
                }
            }
            else
            {
                ResourceLoader.LoadAssetAsync(path, (obj) => UpdateAudioOption(audioSourceData, (AudioClip)obj, (ControlMusic)option, path));
            }                        
        }

        void LoadAudioCallback(Object obj)
        {

        }

		void UpdateAudioOption(AudioSourceData data, AudioClip clip, ControlMusic option, string path)
        {
            if (clip == null) return;

            data.resPath = path;
            data.audioSource.clip = clip;
            ChangeAudioState(data,option);
        }

		void ChangeAudioState(AudioSourceData data,ControlMusic option)
        {
            switch ((ControlMusic)option)
            {
                case ControlMusic.Play:
                    data.audioSource.Play();
                    break;
                case ControlMusic.Pause:
                    data.audioSource.Pause();
                    break;
                case ControlMusic.UnPause:
                    data.audioSource.UnPause();
                    break;
                case ControlMusic.Stop:
                    data.audioSource.Stop();
                    break;
            }
        }

        public enum ControlMusic
        {
            Play = 1,
            Pause,
            UnPause,
            Stop,
        }

        internal class AudioSourceData
        {
            public string resPath;
            public AudioSource audioSource;
            public float defaultVolume;
        }


        internal class AudioPool
        {          
            public List<AudioSourceData> Pool { private set; get; }
			GameObject root;
            public AudioPool(string poolname, Transform parent)
            {
                root = new GameObject(poolname);
                root.transform.parent = parent;
                root.transform.localPosition = Vector3.zero;
                Pool = new List<AudioSourceData>();
            }

            public void AddAudioSource()
            {
				AudioSourceData data = new AudioSourceData();
                data.defaultVolume = 1.0f;
                data.audioSource = root.AddComponent<AudioSource>();
                Pool.Add(data);
            }

        }
    }
}

